package com.ruoyi.qiushi.service.equipment.impl;

import java.math.BigDecimal;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.qiushi.domain.deviceData.QiushiDeviceBloodPressure;
import com.ruoyi.qiushi.domain.equipment.QiushiDevice;
import com.ruoyi.qiushi.domain.equipment.QiushiDeviceType;
import com.ruoyi.qiushi.domain.followup.QiushiFollowRecord;
import com.ruoyi.qiushi.domain.system.QiushiMessage;
import com.ruoyi.qiushi.domain.user.MemberFamily;
import com.ruoyi.qiushi.domain.user.MemberUserFamily;
import com.ruoyi.qiushi.mapper.followup.QiushiFollowRecordMapper;
import com.ruoyi.qiushi.mapper.system.QiushiMessageMapper;
import com.ruoyi.qiushi.mapper.user.MemberUserFamilyMapper;
import com.ruoyi.qiushi.service.deviceData.IQiushiDeviceBloodPressureService;
import com.ruoyi.qiushi.service.equipment.IQiushiDeviceService;
import com.ruoyi.qiushi.service.equipment.IQiushiDeviceTypeService;
import com.ruoyi.qiushi.service.equipment.IQiushiWarningService;
import com.ruoyi.qiushi.service.user.IMemberFamilyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.qiushi.mapper.equipment.QiushiReportMapper;
import com.ruoyi.qiushi.domain.equipment.QiushiReport;
import com.ruoyi.qiushi.service.equipment.IQiushiReportService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 报告Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-15
 */
@Service
public class QiushiReportServiceImpl implements IQiushiReportService {
    private static final Logger log = LoggerFactory.getLogger(QiushiReportServiceImpl.class);
    @Autowired
    private QiushiReportMapper qiushiReportMapper;
    @Autowired
    private IQiushiDeviceBloodPressureService deviceBloodPressureService;
    @Autowired
    private IQiushiDeviceService deviceService;
    @Autowired
    private IMemberFamilyService familyService;
    @Autowired
    private QiushiMessageMapper qiushiMessageMapper;
    @Autowired
    private MemberUserFamilyMapper memberUserFamilyMapper;
    @Autowired
    private QiushiFollowRecordMapper qiushiFollowRecordMapper;
    @Autowired
    private IQiushiDeviceTypeService deviceTypeService;
    @Autowired
    private IQiushiWarningService warningService;

    public int handleSend(QiushiReport qiushiReport) {
        System.out.println();
        System.out.println("tezt:\t" + qiushiReport);
        System.out.println();

        QiushiMessage qiushiMessage = new QiushiMessage();
        qiushiReport.setCreateTime(new Date());
        qiushiReport.setUpdateTime(new Date());
        qiushiReport.setFollowStatus("1");

        MemberUserFamily memberUserFamily = new MemberUserFamily();
        memberUserFamily.setFamilyId(qiushiReport.getFamilyId());
        List<MemberUserFamily> memberUserFamilyList = memberUserFamilyMapper.selectMemberUserFamilyList(memberUserFamily);

        if (memberUserFamilyList.size() == 1) {
            qiushiMessage.setUserId(memberUserFamilyList.get(0).getUserId());
        } else {
            boolean flag = false;
            for (MemberUserFamily temp : memberUserFamilyList) {
                if (temp.getRelation().equals("0")) {
                    qiushiMessage.setUserId(temp.getUserId());
                    flag = true;
                    break;
                }
            }
            if (!flag) qiushiMessage.setUserId(memberUserFamilyList.get(0).getUserId());
        }

        qiushiMessage.setCreateTime(new Date());
        qiushiMessage.setUpdateTime(new Date());
        qiushiMessage.setTitle(qiushiReport.getFormName());
        qiushiMessage.setContent(qiushiReport.getFormName());
        qiushiMessage.setJoinId(qiushiReport.getFormId());
        qiushiMessage.setType("2");

        qiushiMessageMapper.insertQiushiMessage(qiushiMessage);

        QiushiFollowRecord qiushiFollowRecord = new QiushiFollowRecord();
        qiushiFollowRecord.setCreateTime(new Date());
        qiushiFollowRecord.setUpdateTime(new Date());
        qiushiFollowRecord.setFamilyId(qiushiReport.getFamilyId());
        qiushiFollowRecord.setJoinId(qiushiReport.getFormId());
        qiushiFollowRecord.setType("2");

        qiushiFollowRecordMapper.insertQiushiFollowRecord(qiushiFollowRecord);

        return qiushiReportMapper.updateQiushiReport(qiushiReport);
    }

    /**
     * 查询报告
     *
     * @param id 报告主键
     * @return 报告
     */
    @Override
    public QiushiReport selectQiushiReportById(Long id) {
        return qiushiReportMapper.selectQiushiReportById(id);
    }

    /**
     * 查询报告列表
     *
     * @param qiushiReport 报告
     * @return 报告
     */
    @Override
    public List<QiushiReport> selectQiushiReportList(QiushiReport qiushiReport) {
        return qiushiReportMapper.selectQiushiReportList(qiushiReport);
    }

    /**
     * 新增报告
     *
     * @param qiushiReport 报告
     * @return 结果
     */
    @Override
    public int insertQiushiReport(QiushiReport qiushiReport) {
        qiushiReport.setCreateTime(DateUtils.getNowDate());
        return qiushiReportMapper.insertQiushiReport(qiushiReport);
    }

    /**
     * 修改报告
     *
     * @param qiushiReport 报告
     * @return 结果
     */
    @Override
    public int updateQiushiReport(QiushiReport qiushiReport) {
        qiushiReport.setUpdateTime(DateUtils.getNowDate());
        return qiushiReportMapper.updateQiushiReport(qiushiReport);
    }

    /**
     * 批量删除报告
     *
     * @param ids 需要删除的报告主键
     * @return 结果
     */
    @Override
    public int deleteQiushiReportByIds(Long[] ids) {
        return qiushiReportMapper.deleteQiushiReportByIds(ids);
    }

    /**
     * 删除报告信息
     *
     * @param id 报告主键
     * @return 结果
     */
    @Override
    public int deleteQiushiReportById(Long id) {
        return qiushiReportMapper.deleteQiushiReportById(id);
    }


    /**
     * 生成数据
     */
    @Override
    @Transactional
    public void createReport() {
//        //获取上周数据
//        List<QiushiDeviceBloodPressure> list = deviceBloodPressureService.lastWeekData();
        //根据设备id分组
//        Map<String, List<QiushiDeviceBloodPressure>> map = list.stream().collect(Collectors.groupingBy(QiushiDeviceBloodPressure::getEid, Collectors.toList()));
        LocalDate now = LocalDate.now();
        QiushiDeviceType deviceType = deviceTypeService.selectQiushiDeviceTypeById(2L);
        JSONObject deviceStandard = JSONObject.parse(deviceType.getDeviceStandard());//血压设备指标

        //查询出所有需要生成报表的设备列表
        //已绑定，并且未到期
        List<QiushiDevice> devices = deviceService.selectReportDevice();
        for (QiushiDevice device : devices) {
            MemberFamily family = familyService.selectMemberFamilyById(device.getFamilyId());
            if (Objects.isNull(family)) {
                log.info("设备{},family不存在:{}",device.getId(),device.getFamilyId());
                continue;
            }
            //判断是否第一次生成报告
            //  如果上一次生成报告的时间在设备绑定之前， 则获取时间取绑定时间到上周日为止，否则取上周一到上周日的时间
            QiushiReport lastReport = qiushiReportMapper.selectLast(device.getFamilyId(), deviceType.getId());
            LocalDate endLocalDate = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            LocalDate startLocalDate = endLocalDate.plusDays(-7);

            String startTime = startLocalDate.toString()+" 00:00:00";
            String endTime = endLocalDate.toString()+" 00:00:00";

            if (Objects.isNull(lastReport)) {
                //绑定时间-上周日
                startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,device.getUserAddTime());
            } else {
                if(device.getUserAddTime().before(lastReport.getCreateTime())){
                    //上周的时间
                }else{
                    //绑定时间-上周日
                    startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,device.getUserAddTime());
                }
            }

            //查询设备在指定时间内的所有数据
            List<QiushiDeviceBloodPressure> dataList = deviceBloodPressureService.selectLastData(startTime, endTime, device.getDeviceNo());
            if(dataList.isEmpty()){
                log.info("数据不存在{},{},{}",startTime, endTime, device.getDeviceNo());
                continue;
            }

            //标题
            String title = family.getName();
            if("1".equals(family.getSex())){
                title+="（男性|";
            }else if("2".equals(family.getSex())){
                title+="（女性|";
            }else{
                title+="（未知|";
            }

            Instant instant = family.getBirthday().toInstant();
            LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
            int age = Period.between(localDate, now).getYears();
            title = title + age +"岁）第";

            int index = qiushiReportMapper.selectCountByFamilyId(family.getId());
            title = title + (index+1) +"份";

            JSONObject object = new JSONObject();

            object.put("name", family.getName());
            object.put("no",String.format("%07d", family.getId()));  //用户编号 ，补齐七位数
            object.put("createTime", DateUtils.getTime());
            object.put("startTime",startTime);
            object.put("endTime",endTime);
            object.put("title",title);
            Collections.sort(dataList, (data1, data2) -> {
                return data1.getTakeTime().before(data2.getTakeTime()) ? -1 : 1;
            });

            object.put("list", dataList);

            JSONObject total = new JSONObject(); //全程
            total.put("shrink_min", getMinShrink(dataList));
            total.put("shrink_max", getMaxShrink(dataList));
            total.put("shrink_avg", getAvgShrink(dataList));
            total.put("diastole_min", getMinDiastole(dataList));
            total.put("diastole_max", getMaxDiastole(dataList));
            total.put("diastole_avg", getAvgDiastole(dataList));
            total.put("heart_rate_min", getMinHeartRate(dataList));
            total.put("heart_rate_max", getMaxHeartRate(dataList));
            total.put("heart_rate_avg", getAvgHeartRate(dataList));

            object.put("total", total);

            List<QiushiDeviceBloodPressure> morningList = dataList.stream().filter(e -> {
                String timeStr = DateUtils.parseDateToStr("HH:mm:ss", e.getTakeTime());
                LocalTime localTime = LocalTime.parse(timeStr); // 将字符串转换为LocalTime对象
                LocalTime start = LocalTime.parse("06:00:00");
                LocalTime end = LocalTime.parse("09:00:00");
                return (localTime.isAfter(start) && localTime.isBefore(end));
            }).collect(Collectors.toList());

            JSONObject morning = new JSONObject(); //全程
            morning.put("shrink_min", getMinShrink(morningList));
            morning.put("shrink_max", getMaxShrink(morningList));
            morning.put("shrink_avg", getAvgShrink(morningList));
            morning.put("diastole_min", getMinDiastole(morningList));
            morning.put("diastole_max", getMaxDiastole(morningList));
            morning.put("diastole_avg", getAvgDiastole(morningList));
            morning.put("heart_rate_min", getMinHeartRate(morningList));
            morning.put("heart_rate_max", getMaxHeartRate(morningList));
            morning.put("heart_rate_avg", getAvgHeartRate(morningList));

            object.put("morning", morning);

            List<QiushiDeviceBloodPressure> eveningList = dataList.stream().filter(e -> {
                String timeStr = DateUtils.parseDateToStr("HH:mm:ss", e.getTakeTime());
                LocalTime localTime = LocalTime.parse(timeStr); // 将字符串转换为LocalTime对象
                LocalTime start = LocalTime.parse("18:00:00");
                LocalTime end = LocalTime.parse("23:59:59");
                return (localTime.isAfter(start) && localTime.isBefore(end));
            }).collect(Collectors.toList());

            JSONObject evening = new JSONObject(); //全程
            evening.put("shrink_min", getMinShrink(eveningList));
            evening.put("shrink_max", getMaxShrink(eveningList));
            evening.put("shrink_avg", getAvgShrink(eveningList));
            evening.put("diastole_min", getMinDiastole(eveningList));
            evening.put("diastole_max", getMaxDiastole(eveningList));
            evening.put("diastole_avg", getAvgDiastole(eveningList));
            evening.put("heart_rate_min", getMinHeartRate(eveningList));
            evening.put("heart_rate_max", getMaxHeartRate(eveningList));
            evening.put("heart_rate_avg", getAvgHeartRate(eveningList));

            object.put("evening", evening);

            Map<String,String> dateMap = new HashMap<>();
            for (QiushiDeviceBloodPressure pressure : dataList) {
                String date = DateUtils.dateTime(pressure.getTakeTime());
                dateMap.put(date,date);
            }
            //是否定制预警
            if (StringUtils.isNotBlank(device.getDeviceStandard())) {
                deviceStandard = JSONObject.parse(device.getDeviceStandard());
            }

            int sbpCount = 0;//收缩压  高压
            int dbpCount = 0;//舒张压  低压


            for (QiushiDeviceBloodPressure pressure : dataList) {
                String sbp = pressure.getShrink();//收缩压  高压
                String dbp = pressure.getDiastole();//舒张压  低压
                //判断血压是否超出界限
                if (deviceStandard.containsKey("sbp")) {
                    if (StringUtils.isNotBlank(sbp)) {
                        int value = Integer.parseInt(sbp);
                        JSONObject standard = deviceStandard.getJSONObject("sbp");
                        if (standard.containsKey("max")) {
                            int max = standard.getInteger("max");
                            if (value >= max) {
                                sbpCount++;
                            }
                        }
                        if (standard.containsKey("min")) {
                            int min = standard.getInteger("min");
                            if (value <= min) {
                                sbpCount++;
                            }
                        }
                    }
                }
                //舒张压（低压）
                if (deviceStandard.containsKey("dbp")) {
                    if (StringUtils.isNotBlank(dbp)) {
                        int value = Integer.parseInt(dbp);
                        JSONObject standard = deviceStandard.getJSONObject("dbp");
                        if (standard.containsKey("max")) {
                            int max = standard.getInteger("max");
                            if (value >= max) {
                                dbpCount++;
                            }
                        }
                        if (standard.containsKey("min")) {
                            int min = standard.getInteger("min");
                            if (value <= min) {
                                dbpCount++;
                            }
                        }
                    }
                }
            }

            String sbpRate = new BigDecimal(sbpCount).divide(new BigDecimal(dataList.size()),4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).toString();
            String dbpRate = new BigDecimal(dbpCount).divide(new BigDecimal(dataList.size()),4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).toString();

            int warningCount = warningService.warningCount(device.getFamilyId(),device.getId());

            String result = "本次血压检测天数为"+dateMap.size()+"天。总测量次数"+dataList.size()+"次，其中清晨"+morningList.size()+"次，晚间"
                    +eveningList.size()+"次。收缩压超出界限"+sbpCount+"次，占比"+sbpRate+"%，舒张压超出界限"+dbpCount+"次，占比"+dbpRate+"%。"
                    +"清晨平均血压"+morning.get("shrink_avg")+"/"+morning.get("diastole_avg")+"mmHg，"
                    +"晚间平均血压"+evening.get("shrink_avg")+"/"+evening.get("diastole_avg")+"mmHg。\n"
                    +"共发生"+warningCount+"次预警事件。";
            object.put("result",result);

            //生成报表数据
            QiushiReport report = new QiushiReport();
            report.setReportName("血压监测报告");
            report.setDeviceType(device.getDeviceType());
            report.setReportData(JSONObject.toJSONString(object));
            report.setFamilyId(device.getFamilyId());
            report.setCreateTime(new Date());
            report.setUpdateTime(new Date());

            this.insertQiushiReport(report);
        }
    }

    private QiushiDeviceBloodPressure getMaxShrink(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .max(Comparator.comparing(obj -> obj.getShrink()))
                .orElse(null);
    }

    private QiushiDeviceBloodPressure getMinShrink(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .min(Comparator.comparing(obj -> obj.getShrink()))
                .orElse(null);
    }


    private int getAvgShrink(List<QiushiDeviceBloodPressure> list) {
        if(list.isEmpty()){
            return 0;
        }
        double result =  list.stream().map(QiushiDeviceBloodPressure::getShrink).map(Integer::valueOf)
                .mapToInt(num -> num) // 将Stream转换为IntStream
                .average().getAsDouble();
        return new BigDecimal(result).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
    }

    private QiushiDeviceBloodPressure getMaxDiastole(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .max(Comparator.comparing(obj -> obj.getDiastole()))
                .orElse(null);
    }

    private QiushiDeviceBloodPressure getMinDiastole(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .min(Comparator.comparing(obj -> obj.getDiastole()))
                .orElse(null);
    }

    private int getAvgDiastole(List<QiushiDeviceBloodPressure> list) {
        if(list.isEmpty()){
            return 0;
        }
        double result =  list.stream().map(QiushiDeviceBloodPressure::getDiastole).map(Integer::valueOf)
                .mapToInt(num -> num) // 将Stream转换为IntStream
                .average().getAsDouble();
        return new BigDecimal(result).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
    }

    private QiushiDeviceBloodPressure getMaxHeartRate(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .max(Comparator.comparing(obj -> obj.getHeartRate()))
                .orElse(null);
    }

    private QiushiDeviceBloodPressure getMinHeartRate(List<QiushiDeviceBloodPressure> list) {
        return list.stream()
                .min(Comparator.comparing(obj -> obj.getHeartRate()))
                .orElse(null);
    }

    private int getAvgHeartRate(List<QiushiDeviceBloodPressure> list) {
        if(list.isEmpty()){
            return 0;
        }
        double result = list.stream().map(QiushiDeviceBloodPressure::getHeartRate).map(Integer::valueOf)
                .mapToInt(num -> num) // 将Stream转换为IntStream
                .average().getAsDouble();
        return new BigDecimal(result).setScale(0,BigDecimal.ROUND_HALF_UP).intValue();
    }


}
